package com.yixin.hospital.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.lang.tree.Tree;
import cn.hutool.core.lang.tree.TreeNodeConfig;
import cn.hutool.core.lang.tree.TreeUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yixin.hospital.common.ApiResult;
import com.yixin.hospital.entity.domain.JobOffice;
import com.yixin.hospital.entity.domain.VisitTemplate;
import com.yixin.hospital.entity.domain.VisitTemplateJobOffice;
import com.yixin.hospital.entity.dto.req.visitTemplate.VisitTemplateEditTemplateReqDTO;
import com.yixin.hospital.entity.dto.req.visitTemplate.VisitTemplateJobOfficeReqDTO;
import com.yixin.hospital.entity.vo.VisitTemplateJobOfficeVO;
import com.yixin.hospital.mapper.VisitTemplateJobOfficeMapper;
import com.yixin.hospital.service.JobOfficeService;
import com.yixin.hospital.service.VisitTemplateJobOfficeService;
import com.yixin.hospital.service.VisitTemplateService;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

import static com.yixin.hospital.enums.ResponseCodeEnum.JOB_OFFICE_VISIT_TEMPLATE_EXIT;
import static com.yixin.hospital.enums.ResponseCodeEnum.JOB_OFFICE_VISIT_TEMPLATE_NOT_FOUND;

/**
* @author 
* @description 针对表【visit_template_job_office(科室就诊模板映射表)】的数据库操作Service实现
* @createDate 2024-06-30 21:37:13
*/
@Service
public class VisitTemplateJobOfficeServiceImpl extends ServiceImpl<VisitTemplateJobOfficeMapper, VisitTemplateJobOffice>
    implements VisitTemplateJobOfficeService {

    @Resource
    private JobOfficeService jobOfficeService;
    @Resource
    private VisitTemplateService visitTemplateService;

    @Override
    public ApiResult<List<Tree<Integer>>> info(int jobOfficeId) {
        List<VisitTemplateJobOffice> templateCodeList = this.list(new LambdaQueryWrapper<VisitTemplateJobOffice>().eq(VisitTemplateJobOffice::getJobOfficeId, jobOfficeId));
        if (CollectionUtil.isEmpty(templateCodeList)) return ApiResult.error(JOB_OFFICE_VISIT_TEMPLATE_NOT_FOUND);
        List<String> codeList = templateCodeList.stream().map(VisitTemplateJobOffice::getTemplateCode).collect(Collectors.toList());
        List<VisitTemplate> templateList = visitTemplateService.list(new LambdaQueryWrapper<VisitTemplate>().in(VisitTemplate::getTemplateCode, codeList));
        TreeNodeConfig nodeConfig = new TreeNodeConfig();
        List<Tree<Integer>> treeList = TreeUtil.build(templateList, 0, nodeConfig,
                (node, tree) -> {
                    tree.setId(node.getId().intValue());
                    tree.setParentId(node.getPid().intValue());
                    tree.setName(node.getName());
                    tree.putExtra("level", node.getLevel());
                    tree.putExtra("templateCode", node.getTemplateCode());
                    tree.putExtra("templateName", node.getTemplateName());
                    tree.putExtra("level", node.getLevel());
                    tree.putExtra("sort", node.getSort());
                    tree.putExtra("value", "");
                    tree.putExtra("isFocus", false);
                });

        if (CollectionUtil.isEmpty(treeList)) return ApiResult.success(new ArrayList<>());
        for (Tree<Integer> integerTree : treeList) {
            getChildren(integerTree);
        }
        treeList.sort(Comparator.comparing((Tree o) -> (String) o.get("templateCode")).thenComparing((Tree o) -> Integer.valueOf((Integer) o.get("sort"))));
        return ApiResult.success(treeList);
    }

    @Override
    public ApiResult allList() {
        List<VisitTemplateJobOffice> list = this.list(new LambdaUpdateWrapper<VisitTemplateJobOffice>().orderByDesc(VisitTemplateJobOffice::getCreatedTime));
        List<VisitTemplateJobOfficeVO> responseList = new ArrayList<>();
        Map<Long, VisitTemplateJobOfficeVO> responseMap = new HashMap<>();
        for (VisitTemplateJobOffice visitTemplateJobOffice : list) {
            VisitTemplateJobOfficeVO visitTemplateJobOfficeVO = responseMap.get(visitTemplateJobOffice.getJobOfficeId());
            if (Objects.isNull(visitTemplateJobOfficeVO)) {
                visitTemplateJobOfficeVO = new VisitTemplateJobOfficeVO();
                visitTemplateJobOfficeVO.setJobOfficeId(visitTemplateJobOffice.getJobOfficeId());
                responseMap.put(visitTemplateJobOfficeVO.getJobOfficeId(), visitTemplateJobOfficeVO);
                responseList.add(visitTemplateJobOfficeVO);
            }
            JobOffice jobOffice = jobOfficeService.getById(visitTemplateJobOffice.getJobOfficeId());
            if (Objects.nonNull(jobOffice)) visitTemplateJobOfficeVO.setJobOfficeName(jobOffice.getName());
            List<VisitTemplate> visitTemplateList = visitTemplateService.list(new LambdaUpdateWrapper<VisitTemplate>().eq(VisitTemplate::getTemplateCode, visitTemplateJobOffice.getTemplateCode()));
            if (!CollectionUtil.isEmpty(visitTemplateList))
                visitTemplateJobOfficeVO.getVisitTemplateList().add(new VisitTemplateEditTemplateReqDTO(visitTemplateList.get(0).getTemplateCode(), visitTemplateList.get(0).getTemplateName()));

        }
        return ApiResult.success(responseList);
    }

    @Override
    public ApiResult add(VisitTemplateJobOfficeReqDTO visitTemplateAddReqDTO, String userName) {
        List<VisitTemplateJobOffice> jobOfficeExist = this.list(new LambdaUpdateWrapper<VisitTemplateJobOffice>().eq(VisitTemplateJobOffice::getJobOfficeId, visitTemplateAddReqDTO.getJobOfficeId()));
        if (!CollectionUtil.isEmpty(jobOfficeExist)) return ApiResult.error(JOB_OFFICE_VISIT_TEMPLATE_EXIT);
        List<VisitTemplateJobOffice> list = new ArrayList<>();
        for (String visitTemplateCode : visitTemplateAddReqDTO.getVisitTemplateCodeList()) {
            VisitTemplateJobOffice visitTemplateJobOffice = new VisitTemplateJobOffice();
            visitTemplateJobOffice.setJobOfficeId(visitTemplateAddReqDTO.getJobOfficeId());
            visitTemplateJobOffice.setTemplateCode(visitTemplateCode);
            visitTemplateJobOffice.setCreatedBy(userName);
            visitTemplateJobOffice.setUpdatedBy(userName);
            list.add(visitTemplateJobOffice);
        }
        this.saveBatch(list);
        return ApiResult.success();
    }

    @Override
    public ApiResult edit(VisitTemplateJobOfficeReqDTO visitTemplateAddReqDTO, String userName) {
        this.remove(new LambdaUpdateWrapper<VisitTemplateJobOffice>().eq(VisitTemplateJobOffice::getJobOfficeId, visitTemplateAddReqDTO.getJobOfficeId()));
        List<VisitTemplateJobOffice> list = new ArrayList<>();
        for (String visitTemplateCode : visitTemplateAddReqDTO.getVisitTemplateCodeList()) {
            VisitTemplateJobOffice visitTemplateJobOffice = new VisitTemplateJobOffice();
            visitTemplateJobOffice.setJobOfficeId(visitTemplateAddReqDTO.getJobOfficeId());
            visitTemplateJobOffice.setTemplateCode(visitTemplateCode);
            visitTemplateJobOffice.setCreatedBy(userName);
            visitTemplateJobOffice.setUpdatedBy(userName);
            list.add(visitTemplateJobOffice);
        }
        this.saveBatch(list);
        return ApiResult.success();
    }

    private List<Tree<Integer>> getChildren(Tree<Integer> integerTree) {
        if (!CollectionUtil.isEmpty(integerTree.getChildren())) {
            integerTree.getChildren().sort(Comparator.comparing((Tree o) -> (String) o.get("templateCode")).thenComparing((Tree o) -> Integer.valueOf((Integer) o.get("sort"))));
            for (Tree<Integer> child : integerTree.getChildren()) {
                getChildren(child);
            }
        }
        return null;
    }


}




